﻿using System;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Resources;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Markup;
using System.Windows.Navigation;
using System.Xml;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using System.Windows.Threading;
using Microsoft.Phone.Tasks;
using System.Net.NetworkInformation;
using SMARTMobile.Common;

namespace SMARTMobile
{
    public partial class App : Application
    {
        /// <summary>
        /// Provides easy access to the root frame of the Phone Application.
        /// </summary>
        /// <returns>The root frame of the Phone Application.</returns>
        public static PhoneApplicationFrame RootFrame { get; private set; }
        private bool resetApp = false;
        /// <summary>
        /// Constructor for the Application object.
        /// </summary>
        public App()
        {
            // Global handler for uncaught exceptions.
            UnhandledException += Application_UnhandledException;

            // Standard XAML initialization
            InitializeComponent();

            // Phone-specific initialization
            InitializePhoneApplication();

            // Language display initialization
            InitializeLanguage();

            // Show graphics profiling information while debugging.
            if (Debugger.IsAttached)
            {
                // Display the current frame rate counters.
                Application.Current.Host.Settings.EnableFrameRateCounter = true;

                // Show the areas of the app that are being redrawn in each frame.
                //Application.Current.Host.Settings.EnableRedrawRegions = true;

                // Enable non-production analysis visualization mode,
                // which shows areas of a page that are handed off to GPU with a colored overlay.
                //Application.Current.Host.Settings.EnableCacheVisualization = true;

                // Prevent the screen from turning off while under the debugger by disabling
                // the application's idle detection.
                // Caution:- Use this under debug mode only. Application that disables user idle detection will continue to run
                // and consume battery power when the user is not using the phone.
                PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled;
            }

            ////RootFrame.Navigating += RootFrame_Navigating;
            ////RootFrame.Navigated += RootFrame_Navigated;
            RootFrame.BackKeyPress += RootFrame_BackKeyPress;
            if (NetworkInterface.GetIsNetworkAvailable())
            {
                CheckForUpdatedVersion();
            }
        }

        private void RootFrame_BackKeyPress(object sender, System.ComponentModel.CancelEventArgs e)
        {
            // throw new NotImplementedException();
            ////var frame = sender as PhoneApplicationFrame;
            ////if (frame.Source.OriginalString != "/Views/MainPage.xaml")
            ////{
            ////    e.Cancel = true;
            ////    RootFrame.Dispatcher.BeginInvoke(() =>
            ////    {
            ////        RootFrame.Navigate(new Uri("/Views/MainPage.xaml", UriKind.Relative));
            ////    });
            ////}
            ////else
            ////{
            e.Cancel = true;
            ////}
        }

        void RootFrame_Navigated(object sender, NavigationEventArgs e)
        {
            //resetApp = e.NavigationMode == NavigationMode.Reset;
        }

        void RootFrame_Navigating(object sender, NavigatingCancelEventArgs e)
        {
            ////if (resetApp)
            ////{
            ////    ////e.Cancel = true;
            ////    resetApp = false;
            ////    RootFrame.Dispatcher.BeginInvoke(() =>
            ////       {
            ////           RootFrame.Navigate(new Uri("/Views/MainPage.xaml", UriKind.Relative));
            ////       });
            ////}

            ////if (e.Uri.OriginalString == "app://external/")
            ////{
            ////    resetApp = true;
            ////}

        }

        // Code to execute when the application is launching (eg, from Start)
        // This code will not execute when the application is reactivated
        private void Application_Launching(object sender, LaunchingEventArgs e)
        {
        }

        // Code to execute when the application is activated (brought to foreground)
        // This code will not execute when the application is first launched
        private void Application_Activated(object sender, ActivatedEventArgs e)
        {
        }

        // Code to execute when the application is deactivated (sent to background)
        // This code will not execute when the application is closing
        private void Application_Deactivated(object sender, DeactivatedEventArgs e)
        {
        }

        // Code to execute when the application is closing (eg, user hit Back)
        // This code will not execute when the application is deactivated
        private void Application_Closing(object sender, ClosingEventArgs e)
        {
        }

        // Code to execute if a navigation fails
        private void RootFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
        {
            if (Debugger.IsAttached)
            {
                // A navigation has failed; break into the debugger
                Debugger.Break();
            }
        }

        // Code to execute on Unhandled Exceptions
        private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
        {
            if (Debugger.IsAttached)
            {
                // An unhandled exception has occurred; break into the debugger
                Debugger.Break();
            }

            MessageBox.Show("Có lỗi xảy ra:\n" + e.ExceptionObject.ToString());
            e.Handled = true;
        }

        #region Phone application initialization

        // Avoid double-initialization
        private bool phoneApplicationInitialized = false;

        // Do not add any additional code to this method
        private void InitializePhoneApplication()
        {
            if (phoneApplicationInitialized)
                return;

            // Create the frame but don't set it as RootVisual yet; this allows the splash
            // screen to remain active until the application is ready to render.
            RootFrame = new PhoneApplicationFrame();
            RootFrame.Navigated += CompleteInitializePhoneApplication;

            // Handle navigation failures
            RootFrame.NavigationFailed += RootFrame_NavigationFailed;

            // Handle reset requests for clearing the backstack
            RootFrame.Navigated += CheckForResetNavigation;

            // Ensure we don't initialize again
            phoneApplicationInitialized = true;
        }

        // Do not add any additional code to this method
        private void CompleteInitializePhoneApplication(object sender, NavigationEventArgs e)
        {
            // Set the root visual to allow the application to render
            if (RootVisual != RootFrame)
                RootVisual = RootFrame;

            // Remove this handler since it is no longer needed
            RootFrame.Navigated -= CompleteInitializePhoneApplication;
        }

        private void CheckForResetNavigation(object sender, NavigationEventArgs e)
        {
            // If the app has received a 'reset' navigation, then we need to check
            // on the next navigation to see if the page stack should be reset
            if (e.NavigationMode == NavigationMode.Reset)
                RootFrame.Navigated += ClearBackStackAfterReset;
        }

        private void ClearBackStackAfterReset(object sender, NavigationEventArgs e)
        {
            // Unregister the event so it doesn't get called again
            RootFrame.Navigated -= ClearBackStackAfterReset;

            // Only clear the stack for 'new' (forward) and 'refresh' navigations
            if (e.NavigationMode != NavigationMode.New && e.NavigationMode != NavigationMode.Refresh)
                return;

            // For UI consistency, clear the entire page stack
            while (RootFrame.RemoveBackEntry() != null)
            {
                ; // do nothing
            }
        }

        #endregion

        // Initialize the app's font and flow direction as defined in its localized resource strings.
        //
        // To ensure that the font of your application is aligned with its supported languages and that the
        // FlowDirection for each of those languages follows its traditional direction, ResourceLanguage
        // and ResourceFlowDirection should be initialized in each resx file to match these values with that
        // file's culture. For example:
        //
        // AppResources.es-ES.resx
        //    ResourceLanguage's value should be "es-ES"
        //    ResourceFlowDirection's value should be "LeftToRight"
        //
        // AppResources.ar-SA.resx
        //     ResourceLanguage's value should be "ar-SA"
        //     ResourceFlowDirection's value should be "RightToLeft"
        //
        // For more info on localizing Windows Phone apps see http://go.microsoft.com/fwlink/?LinkId=262072.
        //
        private void InitializeLanguage()
        {
            try
            {
                // Set the font to match the display language defined by the
                // ResourceLanguage resource string for each supported language.
                //
                // Fall back to the font of the neutral language if the Display
                // language of the phone is not supported.
                //
                // If a compiler error is hit then ResourceLanguage is missing from
                // the resource file.
                RootFrame.Language = XmlLanguage.GetLanguage(Localization.AppResources.ResourceLanguage);

                // Set the FlowDirection of all elements under the root frame based
                // on the ResourceFlowDirection resource string for each
                // supported language.
                //
                // If a compiler error is hit then ResourceFlowDirection is missing from
                // the resource file.
                FlowDirection flow = (FlowDirection)Enum.Parse(typeof(FlowDirection), Localization.AppResources.ResourceFlowDirection);
                RootFrame.FlowDirection = flow;
            }
            catch
            {
                // If an exception is caught here it is most likely due to either
                // ResourceLangauge not being correctly set to a supported language
                // code or ResourceFlowDirection is set to a value other than LeftToRight
                // or RightToLeft.

                if (Debugger.IsAttached)
                {
                    Debugger.Break();
                }

                throw;
            }
        }

        public static string GetManifestAttributeValue(string attributeName)
        {
            var xmlReaderSettings = new XmlReaderSettings
            {
                XmlResolver = new XmlXapResolver()
            };

            using (var xmlReader = XmlReader.Create("WMAppManifest.xml", xmlReaderSettings))
            {
                xmlReader.ReadToDescendant("App");

                return xmlReader.GetAttribute(attributeName);
            }
        }

        private Task CheckForUpdatedVersion()
        {
            try
            {
                var cultureInfoName = CultureInfo.CurrentUICulture.Name;

                var url = string.Format("http://marketplaceedgeservice.windowsphone.com/v8/catalog/apps/{0}?os={1}&cc={2}&oc=&lang={3}​",
                    "96642fea-6ae3-4481-b3d3-17f08cc28b7d",
                    Environment.OSVersion.Version,
                    cultureInfoName.Substring(cultureInfoName.Length - 2).ToUpperInvariant(),
                    cultureInfoName);

                var request = WebRequest.Create(url);

                return Task.Factory.FromAsync(request.BeginGetResponse, result =>
                {
                    var response = (HttpWebResponse)request.EndGetResponse(result);

                    if (response.StatusCode != HttpStatusCode.OK)
                    {
                        throw new WebException("Http Error: " + response.StatusCode);
                    }

                    using (var outputStream = response.GetResponseStream())
                    {
                        using (var reader = XmlReader.Create(outputStream))
                        {
                            reader.MoveToContent();

                            var aNamespace = reader.LookupNamespace("a");

                            reader.ReadToFollowing("entry", aNamespace);

                            reader.ReadToDescendant("version");

                            var currentVersion = new Version(GetManifestAttributeValue("Version"));
                            var updatedVersion = new Version(reader.ReadElementContentAsString());
                            if (updatedVersion != null && updatedVersion > currentVersion)
                            {
                                //Show an application, using the default ContentType.
                                MarketplaceDetailTask marketplaceDetailTask = new MarketplaceDetailTask();

                                marketplaceDetailTask.ContentIdentifier = "96642fea-6ae3-4481-b3d3-17f08cc28b7d";
                                marketplaceDetailTask.ContentType = MarketplaceContentType.Applications;

                                marketplaceDetailTask.Show();
                            }
                        }
                    }
                }, null);
            }
            catch (Exception)
            {
                return null;
            }
        }

        ////private async void CheckForUpdatedVersion()
        ////{
        ////var currentVersion = new Version(GetManifestAttributeValue("Version"));
        ////var updatedVersion = await GetUpdatedVersion();

        ////if (updatedVersion != null && updatedVersion > currentVersion)
        ////{
        ////    //Show an application, using the default ContentType.
        ////    MarketplaceDetailTask marketplaceDetailTask = new MarketplaceDetailTask();

        ////    marketplaceDetailTask.ContentIdentifier = "74ca07ed-4fc9-4ba5-ab8c-9a4ffcd1c0a7";
        ////    marketplaceDetailTask.ContentType = MarketplaceContentType.Applications;

        ////    marketplaceDetailTask.Show();
        ////}
        ////}
    }
}